/*******************************************************************************
*   功能：       不断把字符串发送到串口助手上,每发两次灯闪烁一次，
                 收到上位机的数据时会马上把原数据发回来。
								 现在又专门增加了一个发送数字的函数
*   注意事项：   串口驱动要手动选择最老的版本，下载线和USB线要同时连接电脑。
*   
********************************************************************************/
#include "reg24le1.h" 
#include "string.h"
#define uchar unsigned char
#define uint unsigned int

code unsigned int UART_BAUD_TBL[7] =
{ 607, 816, 920, 972, 998, 1011, 1015 }; //baudrate: 1200, 2400, 4800, 9600, 19200, 38400, 57600
unsigned char TX_OK = 0;                 //自定义的中断标志位，与S0CON的第一位对应
void delay(int ms);
void UART_Init( unsigned char BaudIndex );
void UART0_SendBuff( unsigned char *buff, unsigned char size );
void UART0_SendStr( char* str );
void UART0_putnum(uint num);

void main( void )
{
	  CLKCTRL = ( CLKCTRL | 0x80 ) & ~0x08;//这个太复杂了不管它，以后直接照抄

    UART_Init( 3 );    //baudrate = 9600
    EA = 1;            //开总中断
    UART0_SendStr( "nRF24LE1 UART Test Start!\r\n" );
	  
    while( 1 )
		{
		    UART0_SendStr( "nRF24LE1 UART Test is running !\r\n" );
			  //UART0_putnum(999);
			  delay(3000);

		}
}

/***      这是经过秒表计时调出来的比较准确的1ms延时函数       ***/
void delay(int ms)     
{
   int x,y;
	 for(x=ms;x>0;x--)
	    for(y=1500;y>0;y--);
}
/***      串口初始化函数，输入参数为发送数据的波特率         ***/

void UART_Init( unsigned char BaudIndex )
{
	IEN0 &= ~( 1<<4 );				//Disable UART0 interrupt while initializeing
	S0CON = ( 1<<6 ) | ( 1<<4 );	//MODE1, Enable receive
	ADCON = 0x80;					//Enable baudrate generator
	PCON |= 0x80;					//mode1
	S0RELL = UART_BAUD_TBL[BaudIndex];
	S0RELH = UART_BAUD_TBL[BaudIndex] >> 8;
	IEN0 |= ( 1<<4 );				//Enable interrupt
    P0DIR |= ( 1<<4 );              //P0.4, RXD, set as input
    P0DIR &= ~( 1<<3 );             //P0.3, TXD, set as output
}

void UART0_SendBuff( unsigned char *buff, unsigned char size )
{  
    while( size -- )
    {
        TX_OK = 0;
        S0BUF = *buff ++;
			while( TX_OK == 0 );     //发送中断标志位置1是TX_OK也同时置1，这里就是在等待发送完成
    }
    TX_OK = 0;                 //把自定义标志位清零，以便下次使用
}

/***      发送字符串的函数，输入参数为字符串     ***/
void UART0_SendStr( char* str )         //从C语言书里查找字符串指针的用法
{
    UART0_SendBuff( ( unsigned char* ) str, strlen( str ) );
}
/***        发送60000以下的数字                ***/
void UART0_putnum(uint num)
{
	    int i;
	    uchar send[10];
	    send[0]=num%10;
	    send[1]=num%100/10;
	    send[2]=num%1000/100;
	    send[3]=num%10000/1000;
	    send[4]=num/10000;
      TX_OK = 0;
	    for(i=4;i>=0;i--)
	    {
        if(1)
				{
				  S0BUF = send[i]+'0';
			    while( TX_OK == 0 ); 
          TX_OK = 0; 
				}
			}
        	
}
/***      串口中断的服务函数，只要收发完一个字节就会进入此中断，里面有LED的设置    ***/
static void UART0_ISR( void ) interrupt INTERRUPT_UART0
{
	  P0DIR &=~((1<<2)|(1<<1));       //set P01 and P02 as output
    if( S0CON & ( 1<<1 ) )          //S0CON的第1位是接收中断标志位，接完一个字节以后，由硬件置1
    {                               //想要再次接收必须软件清零
        //TX ok
        S0CON &= ~( 1<<1 );
        TX_OK = 1;
			  P0 ^=(1<<1);                //Turn on the LED
			  
    }
    else if( S0CON & ( 1<<0 ) )     //S0CON的第0位是接收中断标志位，发完一个字节后，硬件置1软件清零
    {
        //RX ok        
        S0CON &= ~( 1<<0 );
        P0 ^= ( 1<<2 );             //Turn on the LED
			  S0BUF = S0BUF;  //注意这句话，表示收到的东西再发回给上位机，数据只要给力S0BUF,就会自动发送
    }   //注意收发是双工的，这两个S0BUFF其实是不同的
}